/*
 * This file is part of Annuaire.
 *
 * Annuaire is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Annuaire is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with Annuaire.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.miage.annuaire.data.mock;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import javax.servlet.ServletContext;

import org.apache.struts2.ServletActionContext;
import org.miage.annuaire.data.DataAccess;

/**
 * 
 * @author guhumber
 */
public class DataAccessMock implements DataAccess {

	/**
	 * Renvoie les codes des structures de niveau 1.
	 * @return Les codes des structures de niveau 1.
	 */
	@Override
	public ArrayList<String> getStructures() {
		return getStructures(1);
	}

	/**
	 * Renvoie les codes des structures d'un niveau donné.
	 * @param level Le niveau des structures qu'on veut récupérer.
	 * @return Les codes des structures d'un niveau donné.
	 */
	@Override
	public ArrayList<String> getStructures(int level) {
		List<String> structures = getFichierStructures();

		ArrayList<String> codesStructures = new ArrayList<String>(64);

		for (String line : structures) {
			if (line.split(";")[2].equals(Integer.toString(level))) {
				codesStructures.add(line.split(";")[0]);
			}
		}

		return codesStructures;
	}

	@Override
	public String getStructureFather(String struct) {
		List<String> structures = getFichierStructures();
		String codeFather = "100000";

		for (String line : structures) {
			if (line.split(";")[0].equals(struct)) {
				codeFather = line.split(";")[1];
			}

		}
		return codeFather;
	}

	@Override
	public ArrayList<String> getStructureChilds(String struct) {
		List<String> structures = getFichierStructures();

		ArrayList<String> codesStructuresChilds = new ArrayList<String>(64);

		for (String line : structures) {
			if (line.split(";")[1].equals(struct)) {
				codesStructuresChilds.add(line.split(";")[0]);
			}
		}

		return codesStructuresChilds;
	}

	@Override
	public String getShortName(String struct) {
		List<String> structures = getFichierStructures();
		String shortName = "nom de la structure";

		for (String line : structures) {
			if (line.split(";")[0].equals(struct)) {
				shortName = line.split(";")[3];
			}

		}
		return shortName;
	}

	@Override
	public String getCompleteName(String struct) {
		List<String> structures = getFichierStructures();
		String completeName = "nom de la structure";

		for (String line : structures) {
			if (line.split(";")[0].equals(struct)) {
				completeName = line.split(";")[4];
			}

		}
		return completeName;
	}

	@Override
	public String getLeader(String struct) {
		List<String> structures = getFichierStructures();
		String leaderCode = "nom de la structure";

		for (String line : structures) {
			if (line.split(";")[0].equals(struct)) {
				leaderCode = line.split(";")[5];
			}

		}
		return leaderCode;
	}

	@Override
	public String getLeaderTitle(String struct) {
		List<String> structures = getFichierStructures();
		String leaderCode = "nom de la structure";

		for (String line : structures) {
			if (line.split(";")[0].equals(struct)) {
				leaderCode = line.split(";")[5];
			}

		}
		return getFunction(leaderCode);
	}

	@Override
	public String getContact(String struct) {
		List<String> structures = getFichierStructures();
		String contactCode = "nom de la structure";

		for (String line : structures) {
			if (line.split(";")[0].equals(struct)) {
				contactCode = line.split(";")[6];
			}

		}
		return contactCode;
	}

	@Override
	public ArrayList<String> getAsistantLeaders(String struct) {
		List<String> structures = getFichierStructures();
		String[] temp;
		ArrayList<String> codesAsistantLeaders = new ArrayList<String>(64);

		for (String line : structures) {
			if (line.split(";")[0].equals(struct)) {
				temp = line.split(";")[7].split("_");
				for (int i = 0; i < temp.length; i++) {
					codesAsistantLeaders.add(temp[i]);
				}
			}
		}

		return codesAsistantLeaders;
	}

	@Override
	public ArrayList<String> getAsistantLeadersTitle(String struct) {
		List<String> structures = getFichierStructures();
		String[] temp;
		ArrayList<String> titleAsistantLeaders = new ArrayList<String>(64);

		for (String line : structures) {
			if (line.split(";")[0].equals(struct)) {
				temp = line.split(";")[7].split("_");
				for (int i = 0; i < temp.length; i++) {
					titleAsistantLeaders.add(getFunction(temp[i]));
				}
			}
		}

		return titleAsistantLeaders;
	}

	/**
	 * Renvoie les clefs des membres appartenant à une structure donnée.
	 * @param struct Un code de structure.
	 * @return La liste des clefs des membres appartenant à cette structure.
	 */
	@Override
	public ArrayList<String> getMembers(String struct) {
		// Récupération de toutes les lignes du fichier 'Membres.csv'.
		List<String> membres = getFichierMembres();

		// La liste des clefs à renvoyer.
		ArrayList<String> clefsMembres = new ArrayList<String>(16);

		// Pour chaque ligne du fichier .csv, si le code structure (6e token)
		// est égal à celui passé en paramètre, on ajoute le code du membre
		// (1er token) à la liste des clefs.
		for (String membre : membres) {
			if (membre.split(";")[5].equals(struct)) {
				clefsMembres.add(membre.split(";")[0]);
			}
		}

		// Fin.
		return clefsMembres;
	}

	/**
	 * Renvoie le nom d'une personne, en cherchant par son code.
	 * @param person Le code d'une personne.
	 * @return Le nom de la personne cherchée, ou null si la personne n'a pas
	 * été trouvée.
	 */
	@Override
	public String getName(String person) {
		return getCodeMembre(person, 1);
	}

	@Override
	public String getPhone(String person) {
		return getCodeMembre(person, 2);
	}

	@Override
	public String getOffice(String person) {
		return getCodeMembre(person, 3);
	}

	@Override
	public String getFunction(String person) {
		return getCodeMembre(person, 4);
	}

	protected String getCodeMembre(String person, int token) {
		// Récupération de toutes les lignes du fichier 'Membres.csv'.
		List<String> membres = getFichierMembres();

		// Pour chaque ligne du fichier .csv: si le code de la personne (1er
		// token) est égal code 'person' passé en paramètre, on renvoie le token
		// voulu (le 1er token correspond au nom, le 2e au téléphone, ...).
		for (String membre : membres) {
			if (membre.split(";")[0].equals(person)) {
				return membre.split(";")[token];
			}
		}

		// Si on arrive là c'est qu'on a pas trouvé la personne.
		return null;
	}

	protected List<String> chargeFichier(String nomFichier) throws IOException {
		List<String> lignes = new LinkedList<String>();

		InputStream is = null;
		
		ServletContext servletContext = null;
		
		try {
			servletContext = ServletActionContext.getServletContext();
		} catch (NullPointerException e) {
			// Rien.
		}
			
		
		if (servletContext != null) {
			is = servletContext.getResourceAsStream("/resources/mock/"
					+ nomFichier);
		} else {
			is = new FileInputStream(new File("." + File.separator + "web"
					+ File.separator + "resources" + File.separator + "mock"
					+ File.separator + nomFichier));
		}
		
		if (is == null) {
			throw new NullPointerException("Fichier '" + nomFichier
					+ "' introuveble.");
		}
		
		BufferedReader in = new BufferedReader(new InputStreamReader(is));

		in.readLine();
		String ligne = in.readLine();
		while (ligne != null) {
			lignes.add(ligne);
			ligne = in.readLine();
		}

		in.close();

		return lignes;
	}

	protected List<String> getFichierStructures() {
		try {
			return chargeFichier(this.structuresCsv);
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	protected List<String> getFichierMembres() {
		try {
			return chargeFichier(this.membresCsv);
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}
	
	public void setStructuresCsv(String structuresCsv) {
		this.structuresCsv = structuresCsv;
	}
	
	public void setMembresCsv(String membresCsv) {
		this.membresCsv = membresCsv;
	}
	
	private String structuresCsv = "Structures - Demo.csv";
	
	private String membresCsv = "Members - Demo.csv";
}
